﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.OracleClient;
using Kangaroo.Deferreds;
using Kangaroo.IDAL;
using Kangaroo.Model;
using System.Threading;

namespace Kangaroo.DAL.Oracle
{
    public class Alarm : IAlarm
    {
        public AlarmInfo[] ListAlarmsAfter(long key)
        {
            var reader = OracleHelper.ExecuteReader(OracleHelper.ConnectionString,
                CommandType.StoredProcedure, "CRUD_Alarm.ListAlarmsAfter",
                new OracleParameter("pKey", key),
                new OracleParameter("curAlarms", OracleType.Cursor) { Direction = ParameterDirection.Output });
            var alarms = new List<AlarmInfo>();
            while(reader.Read())
            {
                alarms.Add(GetAlarmInfoFromReader(reader));
            }
            reader.Close();
            return alarms.ToArray();
        }

        public AlarmInfo[] ListLastAlarmForEachChannel()
        {
            var reader = OracleHelper.ExecuteReader(OracleHelper.ConnectionString,
                CommandType.StoredProcedure, "CRUD_Alarm.ListLastAlarmForEachChannel",
                new OracleParameter("curAlarms", OracleType.Cursor) { Direction = ParameterDirection.Output });
            var alarms = new List<AlarmInfo>();
            while(reader.Read())
            {
                alarms.Add(GetAlarmInfoFromReader(reader));
            }
            reader.Close();
            return alarms.ToArray();
        }

        public IDeferred<AlarmInfo[]> ListAlarmsAfterAsync(long key)
        {
            return Deferred.New<AlarmInfo[]>(deferred => ThreadPool.QueueUserWorkItem(t =>
            {
                try
                {
                    var dataTable = ListAlarmsAfter(key);
                    deferred.Resolve(dataTable);
                }
                catch (Exception exception)
                {
                    deferred.Reject(exception);
                }
            }));
        }

        public IDeferred<AlarmInfo[]> ListLastAlarmForEachChannelAsync()
        {
            return Deferred.New<AlarmInfo[]>(deferred => ThreadPool.QueueUserWorkItem(t =>
            {
                try
                {
                    var dataTable = ListLastAlarmForEachChannel();
                    deferred.Resolve(dataTable);
                }
                catch (Exception exception)
                {
                    deferred.Reject(exception);
                }
            }));
        }

        private static AlarmInfo GetAlarmInfoFromReader(OracleDataReader reader)
        {
            return new AlarmInfo
            {
                Key = (long)(decimal)reader["Key"],
                ChannelKey = (int)(decimal)reader["ChannelKey"],
                Channel = new ChannelInfo(
                    (int)(decimal)reader["ChannelKey"],
                    reader["DevId"] != DBNull.Value ? (string)reader["DevId"] : "未定义",
                    reader["DevChn"] != DBNull.Value ? (short)(decimal)reader["DevChn"] : (short)(decimal)(-1),
                    reader["EquipId"] != DBNull.Value ? (string)reader["EquipId"] : "未定义",
                    reader["EquipPhase"] != DBNull.Value ? (byte)reader["EquipPhase"] : (byte)(decimal)255),
                AlarmTime = (DateTime)reader["AlarmTime"],
                AlarmType = (string)reader["AlarmType"],
                AlarmLevel = (byte)(decimal)reader["AlarmLevel"],
                AlarmValue = (float)(decimal)reader["AlarmValue"]
            };
        }
    }
}
